package com.jianggujin.redis.dialog;

import java.awt.BorderLayout;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.StringReader;
import java.util.HashMap;
import java.util.Map;

import javax.swing.Box;
import javax.swing.JButton;

import com.jianggujin.redis.MainFrame;
import com.jianggujin.redis.component.JEditorTable;
import com.jianggujin.redis.node.RedisConnection;
import com.jianggujin.redis.util.MessageUtils;

import redis.clients.jedis.params.ClientKillParams;
import redis.clients.jedis.params.ClientKillParams.SkipMe;

public class RedisClientsMonitorDialog extends AbstractDialog {
    private RedisConnection client;
    private JEditorTable clientsTable;
    private JButton refreshBtn;
    private JButton killBtn;
    private JButton cancelBtn;

    private RedisClientsMonitorDialog(MainFrame parent) {
        super(parent);
    }

    private void initCenter() {
        clientsTable = new JEditorTable(false, new String[] { "ID", "Addr", "Fd", "Name", "Age", "Idle", "Flags", "DB",
                "Sub", "PSub", "Multi", "QBuf", "QBuf-Free", "Obl", "Oll", "Omem", "Events", "Cmd" });
        this.add(clientsTable);
    }

    private void initBottom() {
        Box bottom = Box.createHorizontalBox();
        bottom.add(Box.createHorizontalGlue());
        refreshBtn = new JButton("Refresh");
        refreshBtn.addActionListener(e -> handleRefresh());
        bottom.add(refreshBtn);

        killBtn = new JButton("Kill");
        killBtn.addActionListener(e -> handleKill());
        bottom.add(killBtn);

        cancelBtn = new JButton("Cancel");
        cancelBtn.addActionListener(e -> dispose());
        bottom.add(cancelBtn);
        this.add(bottom, BorderLayout.SOUTH);
    }

    @Override
    protected void initComponent() {
        initCenter();
        initBottom();
    }

    @Override
    protected void initDialog() {
        setTitle("Clients Monitor");
        setSize(600, 500);
        super.initDialog();
    }

    private void handleRefresh() {
        String clientList = client.getClient().clientList();
        clientsTable.removeAllRow();
        try (BufferedReader reader = new BufferedReader(new StringReader(clientList))) {
            String line = null;
            while ((line = reader.readLine()) != null) {
                if (line.length() == 0) {
                    continue;
                }
                String[] items = line.split(" +");
                Map<String, String> itemMap = new HashMap<>();
                for (String item : items) {
                    int index = item.indexOf('=');
                    if (index > 0) {
                        itemMap.put(item.substring(0, index).toLowerCase(), item.substring(index + 1));
                    }
                }
                clientsTable.addRow(new Object[] { itemMap.get("id"), itemMap.get("addr"), itemMap.get("fd"),
                        itemMap.get("name"), itemMap.get("age"), itemMap.get("idle"), itemMap.get("flags"),
                        itemMap.get("db"), itemMap.get("sub"), itemMap.get("PSub"), itemMap.get("multi"),
                        itemMap.get("qbuf"), itemMap.get("qbuf-free"), itemMap.get("obl"), itemMap.get("oll"),
                        itemMap.get("omem"), itemMap.get("events"), itemMap.get("cmd") });
            }
        } catch (IOException e) {
        }
    }

    private void handleKill() {
        int index = clientsTable.getSelectedRow();
        if (index < 0 || index >= clientsTable.getRowCount()) {
            MessageUtils.showInfoMessage(this, "Please choose client");
            return;
        }
        if (MessageUtils.showConfirm(this, "Are you sure kill client:" + clientsTable.getValueAt(index, 0) + "?")) {
            ClientKillParams params = new ClientKillParams().skipMe(SkipMe.YES)
                    .addr(clientsTable.getValueAt(index, 1).toString())
                    .id(clientsTable.getValueAt(index, 0).toString());
            client.getClient().clientKill(params);
            handleRefresh();
        }
    }

    public static void monitor(MainFrame parent, RedisConnection client) {
        RedisClientsMonitorDialog dialog = new RedisClientsMonitorDialog(parent);
        dialog.client = client;
        dialog.handleRefresh();
        dialog.setVisible(true);
    }
}
